home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 2 / Gold Medal Software Volume 2 (Gold Medal) (1994).iso / prog / asm_n_z.arj / NOTEPAD4.ASM < prev    next >
Assembly Source File  |  1985-07-27  |  30KB  |  1,004 lines

  1.       PAGE 55,132
  2.       TITLE NOTEPAD4
  3. ;
  4. ;NotePad IV -  NON BIOS VERSION
  5. ;      Permission is granted to copy and distribute freely copies of this
  6. ;      program with the following restrictions:
  7. ;
  8. ;      1) this program be passed in the public domain
  9. ;      2) a fee, beyond the cost of the disk, not be charged
  10. ;      3) improvements not be passed on but rather sent to me
  11. ;       to check for possible incompatibilities with other programs
  12. ;
  13. ;   (Stephen) Randy Davis and Larry Weiss
  14. ;   (214)454-2426
  15. ;
  16. ;       feel free to call with bugs or questions
  17. ;
  18.  
  19. ;PARAMETERS -- MOST OF THESE MAY BE CHANGED TO ANY DESIRED VALUE
  20.  
  21. wndw_ht    equ 24             ;mark the size of the window to open
  22. wndw_wd    equ 40
  23. our_key    equ  07100H        ;scan code - ascii of key to open window
  24.                               ;now scan codes of edit keys  (AltF10)
  25. up_arrow   equ  4800H
  26. down_arrow equ  5000H
  27. left_arrow equ  4B00H
  28. right_arrow equ 4D00H
  29. del_left   equ  0008H         ;user rubout (cntrl H) key
  30. delete     equ  5300H         ;use del (lower right)
  31. insert     equ  5200H
  32. cr         equ  000DH
  33. home       equ  4700H
  34. escape     equ  001BH
  35. tab        equ  7400H         ; ^right arrow
  36. rev_tab    equ  7300H         ; ^left arrow
  37. line_ins   equ  5100H         ;pg down
  38. line_del   equ  4900H         ;pg up
  39. mark_char  equ  4F00H         ;end key
  40. print_char equ  372AH         ;PrtSc* = print note on printer
  41. file_change equ 4A2DH         ;key to update file and get a new one
  42.  
  43. blank      equ  07020H       ;define the character which is a blank
  44. attrib     equ  070H         ;and our default attribute (should agree with blank)
  45. video      equ  10H          ;video BIOS call
  46. inv_attrib equ  007H         ;inverse of 'attrib'
  47.     PAGE
  48. CSEG  SEGMENT PARA PUBLIC 'CODE'
  49.       ASSUME CS:CSEG,DS:CSEG,SS:CSEG,ES:NOTHING   ;STANDARD DECL FOR .COM FILE
  50.  
  51.       ORG  100H
  52.  
  53. Start:
  54.       JMP INSTALL
  55.  
  56. ;PLACE DATA AREA HERE FOR READIBILITY
  57.  
  58. COPYRITE    DB 'Copyright Stephen R. Davis, Larry Weiss 1985  All Rights Reserved'
  59.             DB '(214)454-2426'
  60. SCREENSAVE: DW (WNDW_HT * (WNDW_WD+1)) DUP (BLANK);RESERVE SPACE TO SAVE OPENED WINDOW
  61. LINESAVE:    DW WNDW_WD DUP (BLANK) ;BUFFER FOR LINE DELETE
  62.  
  63. CURSOR_POS  DW 0
  64. OLD_CUR_POS DW 0
  65. SAVESTACK   DW 0,0
  66.  
  67. REQUEST     DB 0              ;REQUEST TYPE
  68. KEY_RQST_HANDLER DD 0         ;ADDRESS OF THE ORIGINAL KEYBOARD REQUEST HANDLER
  69.  
  70. LEFT_MARG  DB   00            ;define the confines of the window
  71. RIGHT_MARG DB   00
  72. TOP_MARG   DB   00
  73. BOT_MARG   DB   00
  74. UPPER_LEFT DW   00
  75.  
  76. MARK       DW   00            ;FLAGS USED IN CHARACTER FEED
  77. FEED_START DW   00            ;ADDRESS IN BUFFER OF BEGIN...
  78. FEED_END   DW   00            ;...AND END OF FEED
  79.  
  80. DISPLAY_SEG DW    00        ;DISPLAY SEGMENT (B000 -> MONOCHROME,
  81.                 ;                 B800 -> GRAPHIX)
  82.  
  83. FILE_NM_LOC DW  00            ;ADDRESS OF FILE NAME (0 -> NO FILE)
  84. PAGE
  85. BEGIN PROC FAR                ;FAR LABEL SINCE ITS ENTERED BY INTERRUPT
  86. MAINLOOP:
  87.       MOV  CS:REQUEST,AH      ;SAVE HIS AX REGISTER
  88.  
  89.       MOV  AX,CS:FEED_START   ;ARE WE IN THE MIDDLE OF FEEDING CHARS...
  90.       CMP  AX,CS:FEED_END     ;...TO THE APPLICATION?
  91.       JZ   NOFEED             ;NO
  92.       JMP  FEED               ;YES
  93. NOFEED:
  94.       MOV  AH,CS:REQUEST      ;RESTORE USERS AX
  95.       PUSHF                   ;CALL OLD INTERRUPT HANDLER (EMULATE INT INSTRUCTION)
  96.       CALL DWORD PTR [CS:KEY_RQST_HANDLER] ;GO AHEAD AND GET THE CHARACTER
  97.       PUSHF                   ;SAVE THE FLAG RETURNED (FOR AH = 1 REQUESTS)
  98.  
  99.       CMP CS:REQUEST,00H      ;WE ARE ONLY INTERESTED IN CHAR. REQUESTS
  100.       JZ  CNTINUE
  101.       JMP FORGET_IT
  102.  
  103. CNTINUE:                      ;YES -- CHECK CHARACTER FOR 'OURS'
  104.       POPF                    ;FOR NON-TYPE 1 REQUESTS DONT NEED TO SAVE FLAGS
  105.       CMP AX,OUR_KEY
  106.       JZ  CNT_AGIN
  107.       JMP RETURN_CHAR
  108.  
  109. CNT_AGIN:                     ;WE GOT IT! GO INTO EDITOR MODE
  110.       MOV CS:SAVESTACK,SP
  111.       MOV CS:SAVESTACK+2,SS
  112.       MOV  AX,CS
  113.       MOV  SS,AX
  114.       MOV  SP,100H
  115.  
  116.       STI                     ;ENABLE INTERRUPTS WHILE PROCESSING CHARACTERS
  117.  
  118.       PUSH BP                 ;SET UP A STACK FRAME
  119.       MOV  BP,SP
  120.       SUB  SP,0EH
  121.       CALL SAVEREG
  122.       MOV  DS,AX
  123.  
  124.       CALL CALC_WINDOW        ;CALCULATE WINDOW EXTREMETIES
  125.  
  126.       CALL READ_CURSOR
  127.       MOV OLD_CUR_POS,DX      ;SAVE THE CURSOR FOR LATER RESTORING
  128.  
  129.       CALL WINDOW_SWAP        ;SWING IN THE EDIT WINDOW (WITH NOTES?)
  130.  
  131.       CALL INSERT_CR          ;PUT THE CARRIAGE RETURNS ON UNPRINTABLE COL.S
  132.  
  133.       MOV DX,CURSOR_POS       ;RESTORE CURSOR IN EDIT WINDOW
  134.       CALL PLACE_CURSOR
  135.  
  136.       CALL EDITOR             ;LET HIM EDIT IN THE WINDOW
  137.  
  138.       CALL READ_CURSOR
  139.       MOV CURSOR_POS,DX       ;SAVE CURSOR IN EDIT WINDOW FOR NEXT EDIT
  140.  
  141.       CMP  MARK,00H          ;CLEAR THE MARK POSITION (IF IT'S SET)
  142.       JZ   NOT_SET
  143.       MOV  DX,MARK
  144.       CALL READ_CHAR          ;GET THE CHARACTER...
  145.       MOV  AH,ATTRIB          ;...PUT ITS ATTRIBUTE BACK TO EVERYONE ELSE'S...
  146.       CALL WRITE_CHAR         ;...AND PUT IT BACK
  147.       MOV  MARK,00H
  148. NOT_SET:
  149.  
  150.       CALL WINDOW_SWAP        ;PUT BACK WHATEVER WAS ORIGINALLY THERE
  151.  
  152.       CALL UPDATE_FILE        ;NOW ATTEMPT TO UPDATE THE DISK FILE
  153.  
  154.       MOV DX,OLD_CUR_POS      ;RESTORE THE CURSOR POSITION
  155.       CALL PLACE_CURSOR
  156.  
  157.       CALL RESTREG
  158.       ADD  SP,0EH
  159.       POP  BP
  160.  
  161.       MOV SS,CS:SAVESTACK+2
  162.       MOV SP,CS:SAVESTACK
  163.  
  164.       MOV AH,00              ;RESTORE REQUEST TO SOMETHING DECENT
  165.       JMP MAINLOOP           ;GO GET ANOTHER CHARACTER TO RETURN HIM
  166.  
  167. RETURN_CHAR:
  168.       IRET                   ;RETURN WITH CHARACTER
  169.  
  170. ;HANDLE REQUEST TYPE 1'S BY FAR RETURNING 2 AND TYPE 2'S BY JUST RETURNING
  171.  
  172. FORGET_IT:
  173.       CMP  CS:REQUEST,1      ;was it a "is char present" request?
  174.       JZ   FI100
  175.  
  176.       POPF                   ;no -- just return whatever BIOS returned
  177.       IRET
  178.  
  179. FI100:
  180.       POPF                   ;yes -- make funny return
  181.       RET 02
  182.       PAGE
  183. ;HERE WE ARE IN THE PROCESS OF FEEDING CHARACTERS TO THE APPLICATION
  184. ;FROM THE WINDOW BUFFER (SCREENSAVE)
  185.  
  186. FEED:
  187.       CMP  CS:REQUEST,1       ;WAS THIS A CHAR TYPE REQUEST?
  188.       JA   KSTAT
  189.                               ;YES -- RETURN HIM CHAR
  190.       PUSH BX                 ;GET THE NEXT CHARACTER FROM THE BUFFER
  191.       CALL SKIP_SPACES        ;STRIP LEADING SPACES
  192.  
  193.       MOV  BX,CS:FEED_START   ;OK - GET THE NEXT CHARACTER WE NEED
  194.       MOV  AX,CS:[BX]
  195.       POP  BX
  196.       XOR  AH,AH              ;WE NO LONGER HAVE THE SCAN CODE, BUT ALL
  197.                               ;ARE ASCII ANYWAY
  198.  
  199.       CMP  CS:REQUEST,0       ;IS THIS A 'GET KEYBOARD CHAR' RQST?
  200.       JNZ  FEED_KEY_STAT
  201.  
  202.       ADD  CS:FEED_START,2    ;YES -- MOVE UP THE POINTER BY 1
  203.       IRET
  204.  
  205. FEED_KEY_STAT:
  206.       STI                     ;NO -- ENABLE INTERRUPTS AND FEED HIM THE
  207.       RET  02                 ;THE Z FLAG CLEAR WITH HIS CHAR
  208.  
  209. KSTAT:
  210.       MOV  AH,CS:REQUEST      ;RESTORE REQUEST TO AH
  211.       CALL DWORD PTR [CS:KEY_RQST_HANDLER] ;PERFORM BIOS CALL -- WE DON'T KNOW
  212.                               ;WHAT HE'S DOING AND WE SHOULDN'T GET IN THE WAY
  213.       IRET                    ;RETURN THE RESULTS TO HIM (WHATEVER THEY ARE)
  214. BEGIN ENDP
  215.       PAGE
  216. BODY  PROC NEAR               ;MAKE SHORT CALLS ONLY TO THE MAIN ROUTINES
  217.  
  218. SKIP_SPACES:
  219. ;TRY TO AVOID FEEDING SPACES WITH NOTHING AFTER THEM ON A LINE --
  220. ;JUST SKIP OVER TO THE RETURN AND FEED THAT ALONE
  221.  
  222.       MOV  BX,CS:FEED_START   ;START WITH THE NEXT FEED CHARACTER
  223. LOOK_AHEAD:
  224.       MOV  AX,CS:[BX]
  225.       CMP  AL,CR              ;IS THIS CHAR A RETURN
  226.       JZ   STRIP_SPACES
  227.       CMP  AL,' '             ;IS THIS CHARACTER ANOTHER SPACE?
  228.       JNZ  GO_ON
  229.       ADD  BX,2               ;YES -- KEEP LOOKING AHEAD
  230.       CMP  BX,CS:FEED_END     ;IS THAT IT?
  231.       JNZ  LOOK_AHEAD
  232.                               ;YES--
  233.       SUB  BX,2               ;RAN OFF THE END -- BACK UP ONE CHAR AT LEAST!
  234. STRIP_SPACES:
  235.       MOV  CS:FEED_START,BX   ;HERE WE FOUND NOTHING BUT SPACES BEFORE THE
  236.                               ;CARRIAGE RETURN -- SKIP THAT!
  237.  
  238. GO_ON:
  239.       RET
  240.       PAGE
  241. CALC_WINDOW:
  242.       MOV AH,0FH              ;FIND OUT VIDEO MODE FOR CALCULATING WINDOW SIZE
  243.       INT VIDEO               ;GO AHEAD AND GET THE CHARACTER
  244.  
  245.       MOV CX,0B000H           ;IS IT MONOCHROME?
  246.       CMP AL,7                ;WELL LOOK FOR MODE 7
  247.       JZ  CW100
  248.       MOV CX,0B800H           ;NO -- ITS GRAPHIX
  249. CW100:
  250.       MOV DISPLAY_SEG,CX      ;SAVE THIS OFF
  251.  
  252.       DEC AH                  ;THIS IS THE NUMBER OF COLS ON SCREEN
  253.       MOV RIGHT_MARG,AH       ;SET UP RIGHT AND LEFT MARGINS
  254.       SUB AH,(WNDW_WD - 1)
  255.       MOV LEFT_MARG,AH
  256.  
  257.       MOV TOP_MARG,0          ;WE HAVE NO INFORMATION ON NUMBER OF ROWS
  258.       MOV BOT_MARG,WNDW_HT-1  ;SO WE MUST ASSUME SOMETHING NORMAL (IT ISNT
  259.                               ;AS CRITICAL ANYWAY)
  260.  
  261.       MOV AL,AH               ;NOW ADD UPPER_LEFT HAND CORNER VALUE
  262.       XOR AH,AH
  263.       MOV UPPER_LEFT,AX
  264.  
  265.  
  266.       CMP CURSOR_POS,0        ;IF THIS IS THE FIRST TIME WEVE DONE THIS...
  267.       JNZ CW200
  268.       MOV CURSOR_POS,AX       ;...PLACE THE CURSOR IN THE UPPER LEFT HAND CORNER
  269.  
  270. CW200:
  271.       RET
  272.       PAGE
  273. INSERT_CR:                      ;INSERT CARRIAGE RETURNS 1 PAST RIGHT MARGIN
  274.       MOV CX,WNDW_HT
  275.       MOV SI,OFFSET SCREENSAVE
  276.       MOV BX,WNDW_WD
  277.       ADD BX,BX                 ;EVERY LOCATION TAKES A WORD, NOT A BYTE
  278. ICR_LOOP:
  279.       ADD SI,BX                 ;GO 1 BEYOND RIGHT MARGIN
  280.       MOV [SI],CR
  281.       ADD SI,2                  ;THAT CR TAKES A SPACE
  282.       LOOP ICR_LOOP
  283.       RET
  284.  
  285. WRITE_POS DW 0
  286.  
  287. WINDOW_SWAP:
  288.     MOV CX,WNDW_HT        ;GET THE NUMBER OF ROWS IN WINDOW AREA
  289.       MOV SI,OFFSET SCREENSAVE;START AT BEGINNING OF BUFFER
  290.       MOV ES,DISPLAY_SEG      ;LOAD UP THE VIDEO SEGMENT
  291.       MOV DI,00
  292.       XOR BX,BX
  293. WS050:
  294.       MOV BL,LEFT_MARG        ;START ON THIS LINE AT THE LEFT MARGIN
  295. WS100:
  296.       SHL  BX,1               ;CHANGE THE COLUMN NUMBER TO BYTE POINTER
  297.       MOV  AX,ES:[BX][DI]     ;GET THE NEXT CHARACTER FROM SCREEN
  298.       XCHG AX,[SI]            ;STORE IT AWAY AND WRITE THE SAVED CHARACTER
  299.       ADD  SI,2               ;AND MOVE SAVE POINTER OVER A WORD
  300.       MOV  ES:[BX][DI],AX     ;NOW RESTORE THAT CHARACTER TO THE SCREEN
  301.       SHR  BX,1               ;PUT THE BYTE OFFSET BACK TO COLUMN NUMBER
  302.       INC  BX
  303.       CMP  BL,RIGHT_MARG      ;ARE WE BEYOND THE END OF THE LINE?
  304.       JNA  WS100
  305.                               ;YES -- SKIP DOWN TO NEXT LINE
  306.       ADD  SI,2               ;SKIP BEYOND CARRIAGE RETURN
  307.       SHL  BX,1
  308.       ADD  DI,BX
  309.       LOOP WS050
  310.       RET
  311.       PAGE
  312. EDITOR:
  313.  
  314. ;first check for "special" keys -- print screen and close file
  315. ;if not one of these, check for edit keys (such as insert, delete, etc.)
  316. ;if not one of those, assume its ascii and just insert it in the notepad
  317. ;return when AltF10 detected.
  318.  
  319. ED100:
  320.       CALL GET_CHAR         ;read a character from the keyboard
  321.       CMP  AX,PRINT_CHAR    ;check for print note first
  322.       JNZ  ED102
  323.  
  324.       CALL PRINTNOTE        ;we need to print the note -- not change it
  325.       MOV  BX,CURSOR_POS     ;in many cases we need the cursor position
  326.       JMP  ED500
  327.  
  328. ED102:
  329.       CMP  AX,FILE_CHANGE   ;is he wanting to close and open a new file
  330.       JNZ  ED103
  331.       CALL CHANGE_FILE
  332.       MOV  BX,CURSOR_POS
  333.       JMP  ED500
  334.  
  335. ED103:
  336.       OR   AL,AL            ;if this is ascii then dont retain scan code
  337.       JZ   ED105
  338.       XOR  AH,AH
  339.  
  340. ED105:
  341.       MOV  BX,CURSOR_POS     ;in many cases we need the cursor position
  342.       CMP  AX,OUR_KEY        ;check for exit
  343.       JNZ  ED110
  344.       JMP  ED800
  345.  
  346. ED110:
  347.       CMP  AX,CR             ;check for each special character individually
  348.       JNZ  ED120
  349.       MOV  BL,LEFT_MARG
  350.       INC  BH
  351.       JMP  ED500
  352. ED120:
  353.       CMP  AX,LEFT_ARROW
  354.       JNZ  ED140
  355.       DEC  BL
  356.       JMP  ED500
  357.  
  358. ED140:
  359.       CMP  AX,RIGHT_ARROW
  360.       JNZ  ED160
  361.       INC  BL
  362.       JMP  ED500
  363.  
  364. ED160:
  365.       CMP   AX,UP_ARROW
  366.       JNZ   ED180
  367.       DEC   BH
  368.       JMP   ED500
  369.  
  370. ED180:
  371.       CMP  AX,DOWN_ARROW
  372.       JNZ  ED200
  373.       INC  BH
  374.       JMP  ED500
  375.  
  376. ED200:
  377.       CMP  AX,HOME
  378.       JNZ  ED205
  379.       MOV  BX,UPPER_LEFT
  380.       JMP  ED500
  381.  
  382. ED205:                       ;tab and back tab functions
  383.       CMP  AX,TAB
  384.       JNZ  ED210
  385.       MOV  CL,1              ;go forward
  386.       JMP  ED213
  387.  
  388. ED210:
  389.       CMP  AX,REV_TAB
  390.       JNZ  ED220
  391.  
  392.       MOV  CL,0FFH           ;go backwards one tab slot
  393.       ADD  DL,CL             ;start one char to left initially
  394.  
  395. ED213:
  396.       CALL READ_CHAR         ;get char at current position
  397.       MOV  CH,AL             ;save it for comparison
  398. ED215:
  399.       ADD  DL,CL             ;move over one character
  400.       CMP  DL,RIGHT_MARG     ;stop at left and right margins (or beyond)
  401.       JGE  ED218
  402.       CMP  DL,LEFT_MARG
  403.       JLE  ED218
  404.  
  405.       CALL READ_CHAR         ;read current character
  406.       CMP  CH,' '            ;if original was a space...
  407.       JNZ  ED216
  408.       CMP  AL,' '            ;...then go until not space
  409.       JZ  ED215
  410.       JMP ED217
  411. ED216:
  412.       CMP AL,' '             ;...else, go until space
  413.       JNZ ED215
  414. ED217:
  415.       CMP  CL,0FFH           ;if we were going backwards (towards left)...
  416.       JNZ  ED218
  417.       ADD  DL,1              ;...then scoot back to the right by 1
  418. ED218:
  419.       MOV  BX,DX
  420.       JMP  ED500
  421.  
  422. ED220:
  423.       CMP  AX,ESCAPE         ;wipe out remainder of line
  424.       JNZ  ED240
  425.       MOV  DX,BX
  426.       CALL ERASE_LINE
  427.       JMP  ED500
  428.  
  429. ED240:
  430.       CMP  AX,DEL_LEFT       ;move cursor left one char and then do normal del
  431.       JNZ  ED260
  432.       DEC  BL
  433.       CMP  BL,LEFT_MARG
  434.       JNB  ED250
  435.       MOV  BL,RIGHT_MARG
  436.       CMP  BH,00
  437.       JZ   ED250
  438.       DEC  BH
  439. ED250:
  440.       JMP  ED270
  441.  
  442. ED260:
  443.       CMP  AX,DELETE         ;in delete char we...
  444.       JNZ  ED280
  445. ED270:
  446.       MOV  CL,RIGHT_MARG
  447.       SUB  CL,BL             ;calculate how many chars to right margin
  448.       XOR  CH,CH
  449.       MOV  DX,BX             ;...start at current cursor position...
  450.       JCXZ ED275
  451. ED272:
  452.       INC  DL                ;...get character just to the right...
  453.       CALL READ_CHAR
  454.       DEC  DL                ;...move left one position...
  455.       CALL WRITE_CHAR        ;...and write it there...
  456.       INC  DL                ;...now do it again for the char to the right...
  457.       LOOP ED272             ;...for the distance from cursor to right margin;...
  458. ED275:
  459.       MOV  AX,BLANK
  460.       CALL WRITE_CHAR
  461.       JMP  ED500
  462.  
  463. ED280:
  464.       CMP  AX,INSERT         ;in the case of insert we do reverse of delete
  465.       JNZ  ED300
  466.       MOV  DH,BH             ;start at the right margin
  467.       MOV  DL,RIGHT_MARG
  468.       MOV  CL,DL             ;caculate number of spaces to right
  469.       SUB  CL,BL
  470.       XOR  CH,CH
  471.       JCXZ ED290
  472. ED285:
  473.       DEC  DL
  474.       CALL READ_CHAR
  475.       INC  DL
  476.       CALL WRITE_CHAR
  477.       DEC  DL
  478.       LOOP ED285
  479. ED290:
  480.       MOV  AX,BLANK
  481.       CALL WRITE_CHAR
  482.       JMP  ED500
  483.  
  484. ED300:
  485.       CMP  AX,LINE_INS       ;check for insert line
  486.       JNZ  ED320
  487.       MOV  DH,BOT_MARG       ;we're going to need that
  488. ED305:
  489.       MOV  DL,LEFT_MARG      ;always start at the far left
  490.       CMP  DH,BH             ;are we on our current line?
  491.       JZ   ED315
  492.                              ;no -- then move it down
  493.       MOV  CX,WNDW_WD
  494. ED310:
  495.       DEC  DH
  496.       CALL READ_CHAR         ;get the character
  497.       INC  DH
  498.       CALL WRITE_CHAR        ;and put it back one line higher
  499.       INC  DL                ;move right one character
  500.       LOOP ED310
  501.  
  502.       DEC  DH                ;now move up a line and do it again
  503.       JMP  ED305
  504. ED315:
  505.       MOV  BL,LEFT_MARG      ;move us over the far left marg
  506.       CALL ERASE_LINE        ;and wipe out the line we are on
  507.       JMP  ED500
  508.  
  509. ED320:
  510.       CMP  AX,LINE_DEL       ;and check for line delete
  511.       JNZ  ED340
  512.  
  513. ED325:
  514.       MOV  DL,LEFT_MARG      ;always start at the far left
  515.       CMP  DH,BOT_MARG       ;are we on the last line?
  516.       JZ   ED335
  517.                              ;no -- then move it up
  518.       MOV  CX,WNDW_WD
  519. ED330:
  520.       INC  DH
  521.       CALL READ_CHAR         ;get the character
  522.       DEC  DH
  523.       CALL WRITE_CHAR        ;and put it back one line lower
  524.       INC  DL                ;move right one character
  525.       LOOP ED330
  526.  
  527.       INC  DH                ;now move down a line and do it again
  528.       JMP  ED325
  529. ED335:
  530.       MOV  BL,LEFT_MARG      ;move us over the far left marg of our line
  531.       CALL ERASE_LINE        ;and wipe out the bottom line
  532.       JMP  ED500
  533.  
  534. ED340:
  535.       CMP  AX,MARK_CHAR      ;check for mark
  536.       JNZ  ED400
  537.  
  538.       MOV  DX,BX
  539.       CMP  MARK,00H          ;if mark isnt set...
  540.       JNZ  ED350
  541.       MOV  MARK,BX           ;...just set it and switch its attrib
  542.       CALL READ_CHAR
  543.       MOV  AH,INV_ATTRIB
  544.       CALL WRITE_CHAR
  545.       JMP  ED500
  546.  
  547. ED350:                       ;else, store off feed start and end addresses
  548.       CALL CONVERT_LOC
  549.       MOV  FEED_START,AX
  550.  
  551.       MOV  DX,MARK
  552.       CALL CONVERT_LOC
  553.       MOV  FEED_END,AX
  554.  
  555.       MOV  CX,FEED_START
  556.       CMP  CX,AX
  557.       JNA  ED355
  558.       MOV  FEED_START,AX
  559.       MOV  FEED_END,CX
  560. ED355:
  561.       JMP  ED800             ;note that this char exits the note pad
  562.  
  563. ED400:                       ;wasnt an edit character -- must be ascii
  564.                              ;just write the character at current position
  565.       MOV  AH,ATTRIB
  566.       CALL W_CHAR
  567.       INC  BL                ;move over one position
  568.  
  569. ED500:                       ;adjust resulting cursor position
  570.       CMP  BL,RIGHT_MARG
  571.       JNA  ED550
  572.       MOV  BL,RIGHT_MARG
  573. ED550:
  574.       CMP  BH,BOT_MARG
  575.       JNA  ED600
  576.       MOV  BH,BOT_MARG
  577. ED600:
  578.       CMP  BL,LEFT_MARG
  579.       JNB  ED650
  580.       MOV  BL,LEFT_MARG
  581. ED650:
  582.       CMP  BH,0FFH           ;special case for a top margin of 0
  583.       JNZ  ED700
  584.       MOV  BH,BOT_MARG
  585. ED700:
  586.       MOV  CURSOR_POS,BX
  587.       MOV  DX,BX             ;be sure and move the cursor to the new
  588.       CALL PLACE_CURSOR      ;position
  589.       JMP  ED100
  590.  
  591. ED800:                       ;exit
  592.       RET
  593.       PAGE
  594. PRINTNOTE:
  595.       CALL P_SPLAT_ROW       ;put a row of splats across the top
  596.                              ;to delineate the note on the printer page
  597.  
  598.       MOV  DX,UPPER_LEFT
  599. PN100:
  600.       CMP   DL,LEFT_MARG     ;put a splat on left hand side also
  601.       JNZ   PN150
  602.       MOV   AL,2AH
  603.       CALL  PRINT_C
  604.       JNZ   PN400            ;don't proceede on timeout of printer
  605.  
  606. PN150:
  607.       CALL  READ_CHAR        ;get the character @ DX
  608.       CALL  PRINT_C          ;and print it
  609.       JNZ   PN400            ;quit immediatly on i/o timeout
  610.  
  611.       CMP   DL,RIGHT_MARG
  612.       JNZ   PN200
  613.  
  614.       MOV   AL,2AH           ;print a right margin delineator
  615.       CALL  PRINT_C
  616.       MOV   AL,0AH          ;print carriage return-line feed after every line
  617.       CALL  PRINT_C
  618.       MOV   AL,0DH
  619.       CALL  PRINT_C
  620.  
  621.       CMP  DH,BOT_MARG       ;are we finished?
  622.       JZ   PN300
  623.                              ;no -- drop down a line
  624.       INC  DH
  625.       MOV  DL,LEFT_MARG
  626.       DEC  DL
  627. PN200:
  628.       INC  DL                ;skip over to next character in note
  629.       JMP  PN100
  630.  
  631. PN300:
  632.       CALL P_SPLAT_ROW
  633.  
  634. PN400:
  635.       RET
  636.  
  637.  
  638. P_SPLAT_ROW:
  639.       MOV  CX,WNDW_WD+2      ;put a row of splats across the page
  640. PS100:
  641.       MOV  AL,2AH
  642.       CALL PRINT_C
  643.       JNZ  PS200             ;return immediately on time out
  644.       LOOP PS100
  645.  
  646.       MOV  AL,0AH
  647.       CALL PRINT_C
  648.       MOV  AL,0DH
  649.       CALL PRINT_C
  650. PS200:
  651.       RET
  652.       PAGE
  653. ;
  654. ; THE FOLLOWING ROUTINE CLOSES THE CURRENT FILE AND ASKS FOR A NEW
  655. ; FILE; IT ATTEMPTS TO OPEN THIS FILE UP AND READ IT AS A NOTE PAD
  656. ;
  657. CHANGE_FILE:
  658.       CALL WINDOW_SWAP       ;PUT THE NOTE PAD INTO THE SAVE BUFFER FOR WRITING
  659.  
  660.       CALL UPDATE_FILE       ;IF CURSOR HOMED, WRITE THE NOTEPAD OUT TO THE CURRENT FILE
  661.  
  662.       MOV  FILE_NM_LOC,0     ;THAT FILE IS NOW CLOSED PERMANENTLY
  663.  
  664.       MOV  DX,UPPER_LEFT     ;ERASE THE TOP LINE AND POSE FILE NAME QUESTION
  665.       MOV  BX,DX
  666.       CALL ERASE_LINE
  667.  
  668.       MOV  DX,BX
  669.       CALL PLACE_CURSOR      ;PUT CURSOR ON LEFT AND ASK FOR FILE NAME
  670.       MOV  BX,OFFSET CF500
  671. CF100:
  672.       MOV  AL,BYTE PTR [BX]
  673.       INC  BX
  674.       CMP  AL,0              ;0 TERMINATES AN ASCIIZ STRING
  675.       JZ   CF200
  676.       MOV  AH,ATTRIB
  677.       CALL W_CHAR
  678.       INC  DL
  679.       CALL PLACE_CURSOR
  680.       JMP  CF100
  681.  
  682. CF200:
  683.       MOV  BX,80H            ;STORE NAME IN PSP
  684.  
  685. CF300:
  686.       CALL GET_CHAR         ;GET FILE NAME UNTIL RETURN
  687.       CMP  AL,0DH            ;CHECK FOR RETURN
  688.       JZ   CF400
  689.       CMP  AL,08H            ;WE DO NEED TO HANDLE DEL CHAR SEPERATLY
  690.       JNZ  CF350
  691.  
  692.       DEC  BX                ;HE'S TRYING TO DELETE THE LAST CHAR
  693.       DEC  DL                ;MOVE THE POINTER BACK IN THE FILE AND DEL CHAR
  694.       MOV  AL,20H            ;ON SCREEN W/ A SPACE
  695.       MOV  AH,ATTRIB
  696.       CALL WRITE_CHAR
  697.       JMP  CF300
  698.  
  699. CF350:
  700.       INC  BX                ;SAVE OFF NEXT CHARACTER OF NAME FIELD
  701.       MOV  BYTE PTR [BX],AL
  702.  
  703.       MOV  AH,ATTRIB
  704.       CALL W_CHAR            ;ECHO CHAR SO HE CAN SEE WHAT HE IS TYPING
  705.       INC  DL
  706.       CALL PLACE_CURSOR
  707.       JMP  CF300
  708.  
  709. CF400:
  710.       SUB  BX,80H            ;CALCULATE CHARACTER COUNT
  711.       MOV  BYTE PTR [80H],BL
  712.  
  713.       MOV  DL,LEFT_MARG      ;NOW ERASE NAME OF FILE AND RESTORE WHAT WAS THERE
  714.       MOV  BX,DX
  715.       CALL RESTORE_LINE
  716.  
  717.       CALL READ_FILE         ;READ UP THE INDICATED FILE INTO SAVE BUFFER
  718.       CALL WINDOW_SWAP       ;NOW PUT NOTE PAD DISPLAY BACK UP
  719.       RET
  720.  
  721. CF500: DB 'ENTER FILE NAME:',0
  722.  
  723. READ_FILE:                   ;READS FILE NAME IN 81 WITH LENGTH COUNT IN 80
  724.                              ;ON SUCCESSFUL READS, RETURNS CARRY CLEARED
  725.  
  726.       MOV  BX,80H            ;FIND BEGINNING OF NAME FIELD
  727.       XOR  CH,CH
  728.       MOV  CL,BYTE PTR [BX]         ;GO GET THE ARGUMENT COUNT FROM THE PSP
  729.       JCXZ  RF300
  730. RF100:                       ;FIND THE BEGINNING OF THE FILE NAME
  731.       INC  BX
  732.       CMP  BYTE PTR [BX],20H
  733.       JNZ  RF150
  734.       LOOP RF100
  735.  
  736. RF150:
  737.       MOV  DI,BX             ;NOW TERMINATE IT WITH A 0
  738.     JCXZ RF300        ;A 0 LENGTH FILE NAME INDICATES NO FILE TO READ
  739.       MOV  FILE_NM_LOC,BX    ;SAVE THE LOCATION OF THE NAME
  740. RF200:
  741.       INC  DI
  742.       LOOP RF200
  743.       MOV  BYTE PTR [DI],0
  744.  
  745.       MOV  AH,3DH            ;OPEN FILE
  746.       MOV  AL,0              ;FILE FOR READ ONLY
  747.       MOV  DX,BX             ;PUT FILE NAME IN GOOD REGISTER
  748.       INT  21H
  749.       JC   RF400             ;CARRY SET INDICATES OPEN ERROR
  750.  
  751.       MOV  BX,AX             ;READ THE FILE INTO THE NOTE PAD AREA
  752.       MOV  CX,(WNDW_HT*(WNDW_WD+1)*2)
  753.       MOV  DX,OFFSET SCREENSAVE
  754.       MOV  AH,3FH
  755.       INT  21H
  756.  
  757.       MOV  AH,3EH            ;CLOSE THE FILE
  758.       INT  21H
  759.  
  760. RF300:
  761.       CLC                    ;MAKE SURE CARRY CLEAR FOR NO ERROR RETURN
  762.       RET
  763.  
  764. RF400:
  765.       RET                    ;LEAVE CARRY SET ON ERROR RETURN
  766.  
  767.  
  768. UPDATE_FILE:
  769.       CMP  FILE_NM_LOC,0     ;IF THERE IS NOT FILE...
  770.       JZ   UP100             ;...THEN JUST SKIP THIS WHOLE THING
  771.  
  772.       MOV  AX,CURSOR_POS     ;UPDATE IF CURSOR HOMED
  773.       CMP  AX,UPPER_LEFT
  774.       JNZ  UP100
  775.  
  776.       MOV  AL,1H             ;OPEN THE FILE FOR WRITING
  777.       MOV  AH,3DH
  778.       MOV  DX,FILE_NM_LOC    ;GET THE FILENAME IN DX
  779.       INT  21H
  780.       JC   UP100             ;IF ERROR ON OPEN, JUST GIVE IT UP
  781.  
  782.       MOV  BX,AX
  783.       MOV  AH,40H            ;WRITE THE FILE
  784.       MOV  CX,(WNDW_HT*(WNDW_WD+1)*2)
  785.       MOV  DX,OFFSET SCREENSAVE
  786.       INT  21H
  787.  
  788.       MOV  AH,3EH
  789.       INT  21H               ;NOW CLOSE THE FILE
  790. UP100:
  791.       RET
  792.  
  793.       PAGE
  794. ;
  795. ; HERE WE PLACE SOME SMALL GENERAL PURPOSE ROUTINES
  796. ;
  797.  
  798. PRINT_C:                     ;print the char in AL on LPT1 (parrallel)
  799.                              ;returns printer status in AH
  800.       PUSH DX
  801.       XOR  DX,DX             ;select LPT1
  802.       XOR  AH,AH             ;select "print"
  803.       INT  17H
  804.       POP  DX
  805.       TEST AH,1              ;set the zero flag if not error,
  806.                              ;clear zero flag if char not printed
  807.       RET
  808.  
  809. PLACE_CURSOR:                ;place cursor at location in dx
  810.       MOV AH,2H
  811.       PUSH BX
  812.       XOR BX,BX
  813.       INT VIDEO
  814.       POP  BX
  815.       RET
  816.  
  817. READ_CURSOR:                  ;read cursor location into dx
  818.       MOV AH,3H
  819.       PUSH BX
  820.       XOR BX,BX
  821.       INT VIDEO
  822.       POP  BX
  823.       RET
  824.  
  825. READ_CHAR:                    ;read screen character at location in dx
  826.       CALL CALC_VID_LOC       ;covert the row and column into location
  827.       MOV  AX,ES:[DI]         ;get the character at that location
  828.       RET
  829.  
  830. R_CHAR:                       ;read screen char at current cursor location
  831.       MOV AH,8H
  832.       PUSH BX
  833.       XOR BH,BH
  834.       INT VIDEO
  835.       POP  BX
  836.       RET
  837.  
  838. WRITE_CHAR:                   ;write attrib/char in ax at location in dx
  839.       PUSH AX                 ;save the attrib from destruction
  840.       CALL CALC_VID_LOC       ;convert the row and column into location
  841.       POP  AX
  842.       MOV ES:[DI],AX
  843.       RET
  844.  
  845. W_CHAR:                       ;write character at current cursor location
  846.       PUSH BX                 ;save bx register
  847.       MOV  BL,AH
  848.       XOR  BH,BH
  849.       PUSH CX                 ;retain cx register also
  850.       MOV  CX,1
  851.       MOV  AH,9H
  852.       INT VIDEO
  853.       POP  CX
  854.       POP  BX
  855.       RET
  856.  
  857. CALC_VID_LOC:                ;convert the row and column in dx into an
  858.                              ;offset into the video display buffer
  859.       XOR  AX,AX
  860.       XOR  DI,DI
  861.       PUSH CX                ;save cx -- some of those who call us need it
  862.       XOR  CX,CX
  863.  
  864.       MOV  AL,RIGHT_MARG     ;get the width of a row
  865.       INC  AX
  866.       MOV  CL,DH             ;put the number of rows into cx
  867.       JCXZ CVL200
  868. CVL100:
  869.       ADD  DI,AX             ;for every row add in another 80/40 columns
  870.       LOOP CVL100
  871. CVL200:
  872.       MOV  AL,DL             ;now move over to the current column
  873.       ADD  DI,AX
  874.  
  875.       POP  CX                ;restore cx
  876.  
  877.       SHL  DI,1              ;now convert this into byte offset
  878.       MOV  ES,DISPLAY_SEG
  879.       RET
  880.  
  881.  
  882. GET_CHAR:                     ;get character from keyboard into ax
  883.       MOV AH,0H
  884.       PUSHF                   ;simulate call to keyboard handler
  885.       CALL DWORD PTR [KEY_RQST_HANDLER]
  886.       RET
  887.  
  888. ERASE_LINE:                   ;erase the current line from dx to right margin
  889.       MOV  CL,RIGHT_MARG
  890.       SUB  CL,BL
  891.       INC  CL
  892.       XOR  CH,CH
  893.       MOV  SI,OFFSET LINESAVE
  894.  
  895. ER100:
  896.       CALL READ_CHAR         ;get the character @ current location
  897.       MOV  [SI],AX
  898.       ADD  SI,2
  899.  
  900.       MOV  AX,BLANK
  901.       CALL WRITE_CHAR
  902.       INC  DL
  903.       LOOP ER100
  904.       RET
  905.  
  906. RESTORE_LINE:                ;restore the current line from dx to right margin
  907.       MOV  CL,RIGHT_MARG
  908.       SUB  CL,BL
  909.       INC  CL
  910.       XOR  CH,CH
  911.       MOV  SI,OFFSET LINESAVE
  912.  
  913. RL100:
  914.       MOV  AX,[SI]           ;get the saved char
  915.       CALL WRITE_CHAR         ;put the saved char where indicated
  916.       ADD  SI,2
  917.       INC  DL
  918.       LOOP RL100
  919.       RET
  920.  
  921. CONVERT_LOC:                 ;convert a location on the screen (in dx) into location
  922.                              ;in the screen save buffer
  923.       MOV  CX,DX
  924.       MOV  AX,OFFSET SCREENSAVE
  925. CL100:
  926.       CMP  CH,TOP_MARG
  927.       JZ   CL200
  928.       ADD  AX,(WNDW_WD+1)*2
  929.       DEC  CH
  930.       JMP  CL100
  931.  
  932. CL200:
  933.       CMP  CL,LEFT_MARG
  934.       JZ   CL300
  935.       ADD  AX,2
  936.       DEC  CL
  937.       JMP  CL200
  938.  
  939. CL300:
  940.       RET
  941.  
  942. SAVEREG:
  943.       MOV  -2[BP],BX          ;save reggies on stack frame
  944.       MOV  -4[BP],CX
  945.       MOV  -6[BP],DX
  946.       MOV  -8[BP],SI
  947.       MOV  -0AH[BP],DI
  948.       MOV  -0CH[BP],DS
  949.       MOV  -0EH[BP],ES
  950.       RET
  951. RESTREG:
  952.       MOV  BX,-2[BP]          ;NOW PUT THE REGGIES BACK AND PULL DOWN
  953.       MOV  CX,-4[BP]          ;THE STACK FRAME
  954.       MOV  DX,-6[BP]
  955.       MOV  SI,-8[BP]
  956.       MOV  DI,-0AH[BP]
  957.       MOV  DS,-0CH[BP]
  958.       MOV  ES,-0EH[BP]
  959.       RET
  960. BODY  ENDP
  961.       PAGE
  962. INSTALL:
  963. ;THIS PROGRAM INSTALLS THE REST OF THE CODE FOR NOTE PAD
  964.  
  965. ;TRY TO READ THE INITIAL FILE UP INTO THE NOTE PAD AREA
  966.  
  967.       CALL READ_FILE
  968.       JNC  GO_AHEAD          ;ON ERROR READING FILE...
  969.                              ;...OUTPUT ERROR MESSAGE AND QUIT
  970.       MOV  DX,OFFSET ERRMSG
  971.       MOV  AH,9H
  972.       INT  21H
  973.       MOV  AH,4CH
  974.       MOV  AL,1              ;SET THE ERROR LEVEL
  975.       INT  21H
  976.  
  977. GO_AHEAD:
  978.       MOV DX,OFFSET MESSAGE  ;OUTPUT 'OK' MESSAGE
  979.       MOV AH,9H
  980.       INT 21H
  981.  
  982.       MOV AX,3516H            ;GET INTERRUPT 16 VECTOR
  983.       INT 21H
  984.       MOV WORD PTR KEY_RQST_HANDLER,BX
  985.       MOV WORD PTR KEY_RQST_HANDLER+2,ES
  986.  
  987.       MOV AX,2516H
  988.       MOV DX,OFFSET BEGIN     ;NOW PUT OUR ROUTINE THERE
  989.       INT 21H
  990.  
  991.       MOV DX,OFFSET INSTALL   ;TERMINATE AND STAY RESIDENT
  992.       ADD DX,100H
  993.       MOV CL,4
  994.       SHR DX,CL
  995.       MOV AH,31H
  996.       INT 21H
  997.  
  998. MESSAGE DB 10,13,'NotePad4 installed',10,13,'Alt-F10 to enter and exit',10,13,'$'
  999.  
  1000. ERRMSG DB 10,13,'NotePad4 not installed',10,13,'Error on file read',10,13,'$'
  1001.  
  1002. CSEG ENDS
  1003.      END START
  1004.